#include "BlockQueue.hpp"
#include <ctime>
#include <sys/types.h>
#include <unistd.h>


// void* productor(void* bq_)//生产
// {
//     BlockQueue<int> * bq=static_cast<BlockQueue<int>*>(bq_);
//     while (true)
//     {
//         int data=rand()%10+1;
//         bq->push(data);
//         std::cout<<"生产数据: "<<data<<std::endl;
        
//     }
//     return nullptr;
// }



// void* consumer(void* bq_)//消费
// {
//     BlockQueue<int> * bq=static_cast<BlockQueue<int>*>(bq_);
//     while (true)
//     {
//         int data;
//         bq->pop(&data);
//         std::cout<<"消费数据: "<<data<<std::endl;
//         sleep(1);
//     }
//     return nullptr;
// }



// int main()
// {
//     srand((unsigned long)time(nullptr)^getpid());
//     BlockQueue<int> * bq=new BlockQueue<int>();

//     pthread_t c,p;
//     pthread_create(&c,nullptr,consumer,bq);
//     pthread_create(&p,nullptr,productor,bq);

//     pthread_join(c,nullptr);
//     pthread_join(p,nullptr);
//     delete bq;
//     return 0;
// }
#include "Task.hpp"
//定义一个队列保存计算任务队列和保存任务队列
template<class C,class S>
class TwoBlockQueue
{
public:
    BlockQueue<C> * c_bq;
    BlockQueue<S> * s_bq;
};

void* productor(void* bqs)//生产
{    
    BlockQueue<CalTask> * bq=(static_cast<TwoBlockQueue<CalTask,SaveTask>*>(bqs))->c_bq;
    while (true)
    {
        int x=rand()%100+1;
        int y=rand()%10;
        int operCode=rand() % oper.size();

        CalTask t(x,y,oper[operCode],mymath);
        bq->push(t);
        std::cout<<"productor->生产任务: "<<t.toTaskString()<<std::endl;
        sleep(1);
    }
    return nullptr;
}



void* consumer(void* bqs)//消费
{
    //拿到计算队列
    BlockQueue<CalTask> * bq=(static_cast<TwoBlockQueue<CalTask,SaveTask>*>(bqs))->c_bq;
    //拿到保存队列
    BlockQueue<SaveTask> * save_bq=(static_cast<TwoBlockQueue<CalTask,SaveTask>*>(bqs))->s_bq;
    while (true)
    {
        //得到任务并处理
        CalTask t;
        bq->pop(&t);
        string result=t();//

        std::cout<<"consumer->消费任务："<<result<<std::endl;

        //存储任务
        SaveTask save(result,Save);
        save_bq->push(save);
        std::cout<<"consumer->推送保存任务完成..."<<std::endl;

        //sleep(1);
    }
    return nullptr;
}

void* saver(void* bqs)
{
    BlockQueue<SaveTask> * save_bq=(static_cast<TwoBlockQueue<CalTask,SaveTask>*>(bqs))->s_bq;
    while (true)
    {
        SaveTask t;
        save_bq->pop(&t);
        t();
        cout<<"saver->保存任务完成"<<endl;
    }
    
    return nullptr;
}




int main()
{
    srand((unsigned long)time(nullptr)^getpid());
    TwoBlockQueue<CalTask,SaveTask> bqs;
    bqs.c_bq=new BlockQueue<CalTask>();
    bqs.s_bq=new BlockQueue<SaveTask>();


    pthread_t c,p,s;
    pthread_create(&c,nullptr,consumer,&bqs);
    pthread_create(&p,nullptr,productor,&bqs);
    pthread_create(&s,nullptr,saver,&bqs);

    pthread_join(c,nullptr);
    pthread_join(p,nullptr);
    pthread_join(s,nullptr);
    delete bqs.c_bq;
    delete bqs.s_bq;
    return 0;
}